package com.csf.service.impl;
import com.csf.config.likeKeyConfig;
import com.csf.dao.LoginTicketMapper;
import com.csf.dao.UserMapper;
import com.csf.entity.LoginTicket;
import com.csf.entity.User;
import com.csf.service.UserService;
import com.csf.util.CommunityActivation;
import com.csf.util.MailUtils;
import com.csf.util.communityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.sql.Time;
import java.util.*;

@Service
public class UserServiceImpl implements UserService, CommunityActivation {

    @Autowired
    private UserMapper userMapper;
//模板引擎
    @Autowired
    private TemplateEngine templateEngine;
//邮箱工具
    @Autowired
    private MailUtils mailUtils;

    @Autowired
    private LoginTicketMapper loginTicketMapper;

//  域名
    @Value("${community.path.domain}")
    private String domain;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public User findUserById(int id) {
//        经常利用id从数据库来查找用户，而用户不经常改变，可以将其放入缓存中
        String userCache = likeKeyConfig.getUser(id);
        User user= getCacheUser(id);
        if (user == null){
            return getInitCacheUser(id);
        }else {
            return user;
        }
    }
//注册流程
    @Override
    public Map<String, Object> register(User user) {
        Map<String,Object> map = new HashMap<>();
        //判断user是否为空
        if (user == null){
            //直接给出参数异常
            throw new IllegalArgumentException("参数不能为空");
        }
        //判断账户
        if (StringUtils.isBlank(user.getUsername())){
            map.put("usernameMsg","用户名不能为空");
            return map;
        }
        //判断密码
        if (StringUtils.isBlank(user.getPassword())){
            map.put("passwordMsg","密码不能为空");
            return map;
        }
        //判断邮箱
        if (StringUtils.isBlank(user.getEmail())){
            map.put("emailMsg","邮箱不能为空");
            return map;
        }

//        判断账户邮箱是否注册
        User Uname = userMapper.findUserByUsername(user.getUsername());
        if (Uname != null){
            map.put("usernameMsg","该账户已被注册");
            return map;
        }
        User userByEmail = userMapper.findUserByEmail(user.getEmail());
        if (userByEmail != null){
            map.put("emailMsg","该邮箱已被注册");
            return map;
        }
//        开始注册
        //密码加强
        user.setSalt(communityUtils.getRandom().substring(0,5));
        user.setPassword(communityUtils.mdFive(user.getPassword()+user.getSalt()));
        user.setType(0);
        user.setCreateTime(new Date());
        user.setStatus(0);
        //设置头像 (%d是占位符，获取随机数后自动填到占位符上)
        user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png",new Random().nextInt(1000)));
        //获取并设置激活码
        user.setActivationCode(communityUtils.getRandom());

        //存入注册用户
        userMapper.InsertUser(user);

        //发送邮箱并激活账户
        Context context = new Context();
        context.setVariable("email",user.getEmail());
        //设置设置激活地址(根据用户id和激活码判断)
        String url = domain+"/activation/"+user.getId()+"/"+user.getActivationCode();
        context.setVariable("url",url);
        //使用模板引擎
        String contexts = templateEngine.process("/mail/activation", context);
        //发送
        mailUtils.sendMail(user.getEmail(),"邮箱激活",contexts);
        return map;
    }

    @Override
    public int activationCode(int userId, String code) {
        User user = userMapper.findUserById(userId);
        if (user.getStatus()==1){
            return AVTIVATION_REPEAT;
//            激活码相同
        }else if(user.getActivationCode().equals(code)){
              userMapper.updateStatus(user.getId(),1);
              return ACTIVATION_SUCCESS;
        }else {
            return ACTIVATION_FAILSE;
        }
    }

    @Override
    public Map<String, Object> login(String username, String password, int Time_Long) {

         Map<String,Object> map = new HashMap<>();

         if (StringUtils.isBlank(username)){
             map.put("usernameMsg","用户名不能为空");
             return map;
         }

         if (StringUtils.isBlank(password)){
             map.put("passwordMsg","密码不能为空");
             return map;
         }

        User user = userMapper.findUserByUsername(username);
        String logPass=communityUtils.mdFive(password+user.getSalt());

        if (user == null){
             map.put("usernameMsg", "该账号不存在!");
             return map;
         }

         if (user.getStatus() == 0){
             map.put("usernameMsg","账户未激活");
         }

         //验证密码
         if (!(user.getPassword()).equals(logPass)){
             map.put("passwordMsg", "密码不正确!");
             return map;
         }
         //  生成登录凭证
         LoginTicket loginTicket = new LoginTicket();
         loginTicket.setUserId(user.getId());
         loginTicket.setTicket(communityUtils.getRandom());
         loginTicket.setStatus(0);
         loginTicket.setExpired(new Date(System.currentTimeMillis() + Time_Long * 1000));
      // loginTicketMapper.insertLoginTicket(loginTicket);
        String tickets = likeKeyConfig.getTicket(loginTicket.getTicket());
        redisTemplate.opsForValue().set(tickets,loginTicket);
        map.put("ticket",loginTicket.getTicket());

        return map;
    }

    @Override
    public void updateTicket(String ticket) {
        int status = 1;
//        loginTicketMapper.updateStatus(ticket,status);
        String ticket1 = likeKeyConfig.getTicket(ticket);
        LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(ticket1);
        loginTicket.setStatus(status);
        redisTemplate.opsForValue().set(ticket1,loginTicket);
    }

    @Override
    public LoginTicket findLoginTicket(String ticket) {
//        LoginTicket loginTicket = loginTicketMapper.findLoginTicket(ticket);
        String ticket1 = likeKeyConfig.getTicket(ticket);
        LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(ticket1);
        return loginTicket;
    }

    @Override
    public User findUserByUsername(String toName) {
        return userMapper.findUserByUsername(toName);
    }

//    利用userId查找用户时，如果缓存中有的话就直接获取
    private User getCacheUser(int userId){
        String userCache = likeKeyConfig.getUser(userId);
        return (User)redisTemplate.opsForValue().get(userCache);
    }
//    缓存中没有，就到数据库中拿，拿到之后放入缓存
    private User getInitCacheUser(int userId){
        User user = userMapper.findUserById(userId);
        String userCache = likeKeyConfig.getUser(userId);
        redisTemplate.opsForValue().set(userCache,user);
        return user;
    }
//    每次对用户更改操作之后，对缓存中的相关用户进行删除操作，不更改状态，避免并发
    private void deleteCache(int userId){

    }

    //获取用户的认证信息
    public Collection<? extends GrantedAuthority> getAuthorities(int userId){
        User user = userMapper.findUserById(userId);
        List<GrantedAuthority> list = new ArrayList<>();
        list.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                switch (user.getType()){
                    case 1:
                        return TYPE_ADMIN;
                    case 2:
                        return TYPE_BZ;
                    default:
                        return TYPE_USER;
                }
            }
        });
        return list;
    }

}
